package com.flower.domain.excel;

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.exception.ExcelDataConvertException;
import com.flower.domain.entity.FlowerEncyclopedia;
import com.flower.service.FlowerEncyclopediaService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 花卉百科数据导入监听器
 */
@Slf4j
@Component
public class EncyclopediaImportListener extends AnalysisEventListener<EncyclopediaExcelData> {

    @Autowired
    private FlowerEncyclopediaService encyclopediaService;
    
    /**
     * 批处理大小
     */
    private static final int BATCH_COUNT = 100;
    
    /**
     * 缓存数据列表
     */
    private List<FlowerEncyclopedia> encyclopediaDataList = new ArrayList<>();
    
    /**
     * 成功导入计数
     */
    private int successCount = 0;
    private int skipCount = 0;
    private int errorCount = 0;

    @Override
    public void invoke(EncyclopediaExcelData data, AnalysisContext context) {
        try {
            // 检查是否已存在同名花卉
            if (encyclopediaService.existsByName(data.getName())) {
                log.info("跳过已存在的花卉: {}", data.getName());
                skipCount++;
                return;
            }
            
            // 转换为实体对象
            FlowerEncyclopedia entity = convertToEntity(data);
            encyclopediaDataList.add(entity);
            successCount++;
            
            // 达到BATCH_COUNT了，需要去存储一次数据库，防止数据几万条数据在内存，容易OOM
            if (encyclopediaDataList.size() >= BATCH_COUNT) {
                saveData();
                encyclopediaDataList.clear();
            }
        } catch (Exception e) {
            log.error("处理第{}行数据失败: {}", context.readRowHolder().getRowIndex() + 1, e.getMessage());
            errorCount++;
        }
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
        // 这里也要保存数据，确保最后遗留的数据也存储到数据库
        saveData();
        
        log.info("Excel导入完成，成功导入{}条数据，跳过{}条重复数据，失败{}条数据", 
                successCount, skipCount, errorCount);
    }

    @Override
    public void onException(Exception exception, AnalysisContext context) {
        log.error("解析Excel异常", exception);
        if (exception instanceof ExcelDataConvertException) {
            ExcelDataConvertException excelException = (ExcelDataConvertException) exception;
            log.error("解析第{}行第{}列数据时发生异常，数据为:{}",
                    excelException.getRowIndex(),
                    excelException.getColumnIndex(),
                    excelException.getCellData());
        }
    }

    /**
     * 保存数据到数据库
     */
    @Transactional(rollbackFor = Exception.class)
    public void saveData() {
        if (encyclopediaDataList.isEmpty()) {
            return;
        }
        
        log.info("开始保存花卉百科数据，本批次数量: {}", encyclopediaDataList.size());
        
        try {
            encyclopediaService.saveBatch(encyclopediaDataList);
            log.info("本批次花卉百科数据保存成功");
        } catch (Exception e) {
            log.error("保存花卉百科数据失败: {}", e.getMessage());
            throw e;
        }
    }

    /**
     * 将Excel数据转换为实体对象
     */
    private FlowerEncyclopedia convertToEntity(EncyclopediaExcelData data) {
        FlowerEncyclopedia entity = new FlowerEncyclopedia();
        entity.setName(data.getName());
        entity.setScientificName(data.getScientificName());
        entity.setAlias(data.getAlias());
        entity.setFamily(data.getFamily());
        entity.setGenus(data.getGenus());
        entity.setOrigin(data.getOrigin());
        entity.setRightPlace(data.getRightPlace());
        entity.setIntroduction(data.getIntroduction());
        entity.setFeatures(data.getFeatures());
        entity.setCultivationDifficulty(data.getCultivationDifficulty());
        entity.setStatus(1); // 设置默认状态
        entity.setDataSource(2); // 设置数据来源为Excel导入
        return entity;
    }

    /**
     * 获取成功导入的数量
     */
    public int getSuccessCount() {
        return successCount;
    }
    
    /**
     * 获取跳过的数量
     */
    public int getSkipCount() {
        return skipCount;
    }
    
    /**
     * 获取失败的数量
     */
    public int getErrorCount() {
        return errorCount;
    }
    
    /**
     * 重置计数（在Controller调用完后）
     */
    public void resetCount() {
        this.successCount = 0;
        this.skipCount = 0;
        this.errorCount = 0;
        this.encyclopediaDataList.clear();
    }
} 